"""
系统设置数据模型
"""
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field, validator
from datetime import datetime
from enum import Enum


class ThemeType(str, Enum):
    """主题类型"""
    LIGHT = "light"
    DARK = "dark"
    AUTO = "auto"


class LanguageType(str, Enum):
    """语言类型"""
    ZH_CN = "zh-CN"
    EN_US = "en-US"
    JA_JP = "ja-JP"


class LogLevel(str, Enum):
    """日志级别"""
    DEBUG = "debug"
    INFO = "info"
    WARNING = "warning"
    ERROR = "error"


class BackupFrequency(str, Enum):
    """备份频率"""
    DAILY = "daily"
    WEEKLY = "weekly"
    MONTHLY = "monthly"


class SMTPEncryption(str, Enum):
    """SMTP加密方式"""
    NONE = "none"
    SSL = "ssl"
    TLS = "tls"


# 基本设置模型
class GeneralSettings(BaseModel):
    """基本设置"""
    system_name: str = Field(default="项目管理系统", description="系统名称")
    system_description: str = Field(default="现代化的项目管理和协作平台", description="系统描述")
    system_version: str = Field(default="1.0.0", description="系统版本")
    timezone: str = Field(default="Asia/Shanghai", description="时区设置")
    language: LanguageType = Field(default=LanguageType.ZH_CN, description="语言设置")
    theme: ThemeType = Field(default=ThemeType.LIGHT, description="主题设置")


# 安全设置模型
class SecuritySettings(BaseModel):
    """安全设置"""
    password_min_length_enabled: bool = Field(default=True, description="启用最小长度限制")
    password_min_length: int = Field(default=8, ge=6, le=20, description="密码最小长度")
    password_require_uppercase: bool = Field(default=True, description="要求包含大写字母")
    password_require_lowercase: bool = Field(default=True, description="要求包含小写字母")
    password_require_numbers: bool = Field(default=True, description="要求包含数字")
    password_require_symbols: bool = Field(default=False, description="要求包含特殊字符")
    session_timeout_enabled: bool = Field(default=True, description="启用会话超时")
    session_timeout_minutes: int = Field(default=120, ge=5, le=1440, description="会话超时时间(分钟)")
    login_attempts_enabled: bool = Field(default=True, description="启用登录失败限制")
    max_login_attempts: int = Field(default=5, ge=3, le=10, description="最大登录尝试次数")


# 通知设置模型
class NotificationSettings(BaseModel):
    """通知设置"""
    email_enabled: bool = Field(default=False, description="启用邮件通知")
    smtp_host: str = Field(default="", description="SMTP服务器")
    smtp_port: int = Field(default=587, ge=1, le=65535, description="SMTP端口")
    smtp_username: str = Field(default="", description="SMTP用户名")
    smtp_password: str = Field(default="", description="SMTP密码")
    smtp_encryption: SMTPEncryption = Field(default=SMTPEncryption.TLS, description="加密方式")
    notify_task_assigned: bool = Field(default=True, description="任务分配通知")
    notify_task_completed: bool = Field(default=True, description="任务完成通知")
    notify_project_update: bool = Field(default=True, description="项目更新通知")
    notify_deadline_reminder: bool = Field(default=True, description="截止日期提醒")


# 系统配置模型
class SystemSettings(BaseModel):
    """系统配置"""
    max_file_size_mb: int = Field(default=50, ge=1, le=1024, description="最大文件大小(MB)")
    allowed_file_types: str = Field(
        default="jpg,jpeg,png,gif,pdf,doc,docx,xls,xlsx,ppt,pptx,txt,md",
        description="允许的文件类型"
    )
    db_pool_size: int = Field(default=20, ge=5, le=100, description="数据库连接池大小")
    db_query_timeout: int = Field(default=30, ge=5, le=300, description="查询超时时间(秒)")
    cache_enabled: bool = Field(default=True, description="启用缓存")
    cache_ttl_minutes: int = Field(default=60, ge=1, le=1440, description="缓存过期时间(分钟)")
    log_level: LogLevel = Field(default=LogLevel.INFO, description="日志级别")
    log_retention_days: int = Field(default=30, ge=1, le=365, description="日志保留天数")


# 备份设置模型
class BackupSettings(BaseModel):
    """备份设置"""
    auto_backup_enabled: bool = Field(default=False, description="启用自动备份")
    backup_frequency: BackupFrequency = Field(default=BackupFrequency.WEEKLY, description="备份频率")
    backup_time: str = Field(default="02:00", description="备份执行时间，格式HH:mm")
    max_backup_count: int = Field(default=10, ge=1, le=30, description="备份保留份数")
    backup_compression: bool = Field(default=True, description="是否压缩备份文件")
    backup_encryption: bool = Field(default=False, description="是否启用备份加密")

    @validator("backup_time")
    def validate_backup_time(cls, value: str) -> str:
        if not value:
            return "02:00"
        try:
            datetime.strptime(value, "%H:%M")
        except ValueError as exc:
            raise ValueError("备份时间格式必须为HH:mm") from exc
        return value


# 完整系统设置模型
class SystemSettingsModel(BaseModel):
    """完整系统设置"""
    id: Optional[str] = Field(None, description="设置ID")
    general: GeneralSettings = Field(default_factory=GeneralSettings, description="基本设置")
    security: SecuritySettings = Field(default_factory=SecuritySettings, description="安全设置")
    notification: NotificationSettings = Field(default_factory=NotificationSettings, description="通知设置")
    system: SystemSettings = Field(default_factory=SystemSettings, description="系统配置")
    backup: BackupSettings = Field(default_factory=BackupSettings, description="备份设置")
    created_at: Optional[datetime] = Field(None, description="创建时间")
    updated_at: Optional[datetime] = Field(None, description="更新时间")
    updated_by: Optional[str] = Field(None, description="更新者ID")

    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat() if v else None
        }


# 设置更新请求模型
class GeneralSettingsUpdate(BaseModel):
    """基本设置更新"""
    system_name: Optional[str] = None
    system_description: Optional[str] = None
    timezone: Optional[str] = None
    language: Optional[LanguageType] = None
    theme: Optional[ThemeType] = None


class SecuritySettingsUpdate(BaseModel):
    """安全设置更新"""
    password_min_length_enabled: Optional[bool] = None
    password_min_length: Optional[int] = Field(None, ge=6, le=20)
    password_require_uppercase: Optional[bool] = None
    password_require_lowercase: Optional[bool] = None
    password_require_numbers: Optional[bool] = None
    password_require_symbols: Optional[bool] = None
    session_timeout_enabled: Optional[bool] = None
    session_timeout_minutes: Optional[int] = Field(None, ge=5, le=1440)
    login_attempts_enabled: Optional[bool] = None
    max_login_attempts: Optional[int] = Field(None, ge=3, le=10)


class NotificationSettingsUpdate(BaseModel):
    """通知设置更新"""
    email_enabled: Optional[bool] = None
    smtp_host: Optional[str] = None
    smtp_port: Optional[int] = Field(None, ge=1, le=65535)
    smtp_username: Optional[str] = None
    smtp_password: Optional[str] = None
    smtp_encryption: Optional[SMTPEncryption] = None
    notify_task_assigned: Optional[bool] = None
    notify_task_completed: Optional[bool] = None
    notify_project_update: Optional[bool] = None
    notify_deadline_reminder: Optional[bool] = None


class SystemSettingsUpdate(BaseModel):
    """系统配置更新"""
    max_file_size_mb: Optional[int] = Field(None, ge=1, le=1024)
    allowed_file_types: Optional[str] = None
    db_pool_size: Optional[int] = Field(None, ge=5, le=100)
    db_query_timeout: Optional[int] = Field(None, ge=5, le=300)
    cache_enabled: Optional[bool] = None
    cache_ttl_minutes: Optional[int] = Field(None, ge=1, le=1440)
    log_level: Optional[LogLevel] = None
    log_retention_days: Optional[int] = Field(None, ge=1, le=365)


class BackupSettingsUpdate(BaseModel):
    """备份设置更新"""
    auto_backup_enabled: Optional[bool] = None
    backup_frequency: Optional[BackupFrequency] = None
    backup_time: Optional[str] = Field(None, description="备份执行时间，格式HH:mm")
    max_backup_count: Optional[int] = Field(None, ge=1, le=30)
    backup_compression: Optional[bool] = None
    backup_encryption: Optional[bool] = None
    backup_retention_count: Optional[int] = Field(None, ge=1, le=30, description="兼容旧字段：备份保留份数")

    @validator("backup_time")
    def validate_backup_time(cls, value: Optional[str]) -> Optional[str]:
        if value is None:
            return value
        try:
            datetime.strptime(value, "%H:%M")
        except ValueError as exc:
            raise ValueError("备份时间格式必须为HH:mm") from exc
        return value

    class Config:
        extra = "ignore"


# 备份历史模型
class BackupRecord(BaseModel):
    """备份记录"""
    id: Optional[str] = Field(None, description="备份ID")
    filename: str = Field(..., description="备份文件名")
    size: int = Field(..., description="文件大小(字节)")
    status: str = Field(..., description="备份状态")
    created_at: datetime = Field(..., description="创建时间")
    created_by: Optional[str] = Field(None, description="创建者ID")

    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat() if v else None
        }


class BackupRecordList(BaseModel):
    """备份记录列表"""
    items: List[BackupRecord] = Field(default_factory=list, description="备份记录列表")
    total: int = Field(default=0, description="总数")


# 邮件测试请求模型
class EmailTestRequest(BaseModel):
    """邮件测试请求"""
    to_email: str = Field(..., description="收件人邮箱")
    subject: Optional[str] = Field("系统设置邮件测试", description="邮件主题")
    content: Optional[str] = Field("这是一封来自项目管理系统的测试邮件。", description="邮件内容")


# 响应模型
class SystemSettingsResponse(BaseModel):
    """系统设置响应"""
    general: GeneralSettings
    security: SecuritySettings
    notification: NotificationSettings
    system: SystemSettings
    backup: BackupSettings
    updated_at: Optional[datetime] = None
    updated_by: Optional[str] = None

    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat() if v else None
        }